﻿using System;
using GeoAPI.Geometries;
using NetTopologySuite.Geometries;

namespace NetTopologySuite.Simplify
{
	public class OldVWLineSimplifier
	{
		public static Coordinate[] Simplify(Coordinate[] pts, double distanceTolerance)
		{
			return new OldVWLineSimplifier(pts, distanceTolerance).Simplify();
		}

		public OldVWLineSimplifier(Coordinate[] pts, double distanceTolerance)
		{
			this._pts = pts;
			this._tolerance = distanceTolerance * distanceTolerance;
		}

		public Coordinate[] Simplify()
		{
			OldVWLineSimplifier.VWVertex vwvertex = OldVWLineSimplifier.VWVertex.BuildLine(this._pts);
			double num = this._tolerance;
			do
			{
				num = this.SimplifyVertex(vwvertex);
			}
			while (num < this._tolerance);
			Coordinate[] coordinates = vwvertex.GetCoordinates();
			if (coordinates.Length >= 2)
			{
				return coordinates;
			}
			return new Coordinate[]
			{
				coordinates[0],
				new Coordinate(coordinates[0])
			};
		}

		private double SimplifyVertex(OldVWLineSimplifier.VWVertex vwLine)
		{
			OldVWLineSimplifier.VWVertex vwvertex = vwLine;
			double num = vwvertex.GetArea();
			OldVWLineSimplifier.VWVertex vwvertex2 = null;
			while (vwvertex != null)
			{
				double area = vwvertex.GetArea();
				if (area < num)
				{
					num = area;
					vwvertex2 = vwvertex;
				}
				vwvertex = vwvertex.Next;
			}
			if (vwvertex2 != null && num < this._tolerance)
			{
				vwvertex2.Remove();
			}
			if (!vwLine.IsLive)
			{
				return -1.0;
			}
			return num;
		}

		private readonly Coordinate[] _pts;

		private readonly double _tolerance;

		internal class VWVertex
		{
			public static OldVWLineSimplifier.VWVertex BuildLine(Coordinate[] pts)
			{
				OldVWLineSimplifier.VWVertex vwvertex = null;
				OldVWLineSimplifier.VWVertex vwvertex2 = null;
				for (int i = 0; i < pts.Length; i++)
				{
					OldVWLineSimplifier.VWVertex vwvertex3 = new OldVWLineSimplifier.VWVertex(pts[i]);
					if (vwvertex == null)
					{
						vwvertex = vwvertex3;
					}
					vwvertex3.Prev = vwvertex2;
					if (vwvertex2 != null)
					{
						vwvertex2.Next = vwvertex3;
						vwvertex2.UpdateArea();
					}
					vwvertex2 = vwvertex3;
				}
				return vwvertex;
			}

			public VWVertex(Coordinate pt)
			{
				this._pt = pt;
			}

			public OldVWLineSimplifier.VWVertex Prev
			{
				get
				{
					return this._prev;
				}
				set
				{
					this._prev = value;
				}
			}

			public OldVWLineSimplifier.VWVertex Next
			{
				get
				{
					return this._next;
				}
				set
				{
					this._next = value;
				}
			}

			public void UpdateArea()
			{
				if (this.Prev == null || this.Next == null)
				{
					this._area = double.MaxValue;
					return;
				}
				double value = Triangle.Area(this.Prev._pt, this._pt, this.Next._pt);
				this._area = System.Math.Abs(value);
			}

			public double GetArea()
			{
				return this._area;
			}

			public bool IsLive
			{
				get
				{
					return this._isLive;
				}
			}

			public OldVWLineSimplifier.VWVertex Remove()
			{
				OldVWLineSimplifier.VWVertex prev = this.Prev;
				OldVWLineSimplifier.VWVertex next = this.Next;
				OldVWLineSimplifier.VWVertex vwvertex = null;
				if (this.Prev != null)
				{
					this.Prev.Next = next;
					this.Prev.UpdateArea();
					vwvertex = this.Prev;
				}
				if (this.Next != null)
				{
					this.Next.Prev = prev;
					this.Next.UpdateArea();
					if (vwvertex == null)
					{
						vwvertex = this.Next;
					}
				}
				this._isLive = false;
				return vwvertex;
			}

			public Coordinate[] GetCoordinates()
			{
				CoordinateList coordinateList = new CoordinateList();
				OldVWLineSimplifier.VWVertex vwvertex = this;
				do
				{
					coordinateList.Add(vwvertex._pt, false);
					vwvertex = vwvertex.Next;
				}
				while (vwvertex != null);
				return coordinateList.ToCoordinateArray();
			}

			private const double MaxArea = 1.7976931348623157E+308;

			private readonly Coordinate _pt;

			private OldVWLineSimplifier.VWVertex _prev;

			private OldVWLineSimplifier.VWVertex _next;

			private double _area = double.MaxValue;

			private bool _isLive = true;
		}
	}
}
